package org.hitchhike.core.domain;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.validator.constraints.NotEmpty;
import org.hitchhike.common.domain.BaseEntity;
import org.hitchhike.core.enums.UserStateEnum;
import org.hitchhike.core.exception.JsonException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@Entity
@Table(name = "tb_user")
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity implements UserDetails {

  private static final long serialVersionUID = 1L;
  /**
   * 用户名
   */
  @NotEmpty(message = "用户名不能为空")
  @Column(unique = true)
  private String username;
  /**
   * 密码
   */
  @NotEmpty(message = "密码不能为空")
  private String password;
  /**
   * 姓名（不可修改）
   */
  @NotEmpty(message = "姓名不能为空")
  private String realName;
  /**
   * 性别
   */
  private int sex = 1;

  public String getSexName() {
    String sexName = "";
    switch (this.sex) {
      case 0:
        sexName = "女";
        break;
      case 1:
        sexName = "男";
        break;
      default:
        break;
    }
    return sexName;
  }

  /**
   * 年龄
   */
  private int age = 1;

  /**
   * 照片
   */
  @Lob
  @Basic(fetch = FetchType.LAZY)
  private byte[] image;
  /**
   * 
   */
  @Transient
  private String repassword;

  @Enumerated(EnumType.STRING)
  private UserStateEnum userState;

  public String getUserStateName() {
    String userStateName = "";
    switch (this.userState) {
      case DISABLED:
        userStateName = "停用";
        break;
      case ENABLED:
        userStateName = "启用";
        break;
      case FINISHED:
        userStateName = "完成";
        break;
      case PENDING:
        userStateName = "待定";
        break;
      default:
        break;
    }
    return userStateName;
  }

  /**
   * 用户类型
   */
  private int userType;

  @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
  private List<Order> orders;

  @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  @JoinColumn(name = "passenger_id")
  private Passenger passenger;

  @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  @JoinColumn(name = "driver_id")
  private Driver driver;

  @Override
  public Collection<? extends GrantedAuthority> getAuthorities() {
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    authorities.add(new SimpleGrantedAuthority(String.valueOf(this.userType)));
    return authorities;
  }

  @Override
  public boolean isAccountNonExpired() {
    return true;
  }

  @Override
  public boolean isAccountNonLocked() {
    return true;
  }

  @Override
  public boolean isCredentialsNonExpired() {
    return true;
  }

  @Override
  public boolean isEnabled() {
    return true;
  }

  public String getImageName() {
    if (this.image != null) {
      try {
        return new String(this.image, "UTF-8");
      } catch (UnsupportedEncodingException e) {
        throw new JsonException(e.getMessage());
      }
    }
    return null;
  }

  public Driver getDriverInfo() {
    if (this.getDriver() == null) {
      return new Driver();
    } else {
      return this.getDriver();
    }
  }

  public Passenger getPassengerInfo() {
    if (this.getPassenger() == null) {
      return new Passenger();
    } else {
      return this.getPassenger();
    }
  }

}
